import { app, BrowserWindow, shell, ipcMain, dialog, Menu, globalShortcut } from "electron";
import { release } from "node:os";
import { join, dirname } from "node:path";
import fs from "node:fs";
const Store = require("electron-store");
const store = new Store();

// The built directory structure
//
// ├─┬ dist-electron
// │ ├─┬ main
// │ │ └── index.js    > Electron-Main
// │ └─┬ preload
// │   └── index.js    > Preload-Scripts
// ├─┬ dist
// │ └── index.html    > Electron-Renderer
//
process.env.DIST_ELECTRON = join(__dirname, "..");
process.env.DIST = join(process.env.DIST_ELECTRON, "../dist");
process.env.PUBLIC = process.env.VITE_DEV_SERVER_URL ? join(process.env.DIST_ELECTRON, "../public") : process.env.DIST;

// Disable GPU Acceleration for Windows 7
if (release().startsWith("6.1")) app.disableHardwareAcceleration();

// Set application name for Windows 10+ notifications
if (process.platform === "win32") app.setAppUserModelId(app.getName());

if (!app.requestSingleInstanceLock()) {
  app.quit();
  process.exit(0);
}

// Remove electron security warnings
// This warning only shows in development mode
// Read more on https://www.electronjs.org/docs/latest/tutorial/security
// process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'

let win: BrowserWindow | null = null;
let editerWin: BrowserWindow | null = null;
// Here, you can also use other preload
const preload = join(__dirname, "../preload/index.js");
const url = process.env.VITE_DEV_SERVER_URL;
const indexHtml = join(process.env.DIST, "index.html");

async function createWindow() {
  win = new BrowserWindow({
    title: "Main window",
    icon: join(process.env.PUBLIC, "favicon.ico"),
    width: 910,
    height: 636,
    minWidth: 910,
    minHeight: 636,
    webPreferences: {
      preload,
      // Warning: Enable nodeIntegration and disable contextIsolation is not secure in production
      // Consider using contextBridge.exposeInMainWorld
      // Read more on https://www.electronjs.org/docs/latest/tutorial/context-isolation
      nodeIntegration: true
      // contextIsolation: false
    }
  });

  if (process.env.VITE_DEV_SERVER_URL) {
    // electron-vite-vue#298
    win.loadURL(url);
    // Open devTool if the app is not packaged
    win.webContents.openDevTools();
  } else {
    win.loadFile(indexHtml);
  }

  // Test actively push message to the Electron-Renderer
  win.webContents.on("did-finish-load", () => {
    win?.webContents.send("main-process-message", new Date().toLocaleString());
  });

  // Make all links open with the browser, not with the application
  win.webContents.setWindowOpenHandler(({ url }) => {
    if (url.startsWith("https:")) shell.openExternal(url);
    return { action: "deny" };
  });
  // win.webContents.on('will-navigate', (event, url) => { }) #344

  // 注册一个'CommandOrControl+F' 快捷键监听器
  // const ret = globalShortcut.register("CommandOrControl+F", () => {
  //   if (editerWin) {
  //     editerWin.webContents.send("cmdOrCtrlF");
  //   }
  // });
  // if (!ret) {
  //   console.log("registration failed");
  // }
  // 检查快捷键是否注册成功
  // console.log(globalShortcut.isRegistered('CommandOrControl+F'))
}

app.whenReady().then(createWindow);

app.on("window-all-closed", () => {
  win = null;
  if (process.platform !== "darwin") app.quit();
});

app.on("second-instance", () => {
  if (win) {
    // Focus on the main window if the user tried to open another
    if (win.isMinimized()) win.restore();
    win.focus();
  }
});

app.on("activate", () => {
  const allWindows = BrowserWindow.getAllWindows();
  if (allWindows.length) {
    allWindows[0].focus();
  } else {
    createWindow();
  }
});

app.on("will-quit", () => {
  // 注销快捷键
  // globalShortcut.unregister("CommandOrControl+F");
});

// New window example arg: new windows url
ipcMain.handle("open-win", (_, arg) => {
  let winData: any = {
    webPreferences: {
      preload,
      nodeIntegration: true
      // contextIsolation: false
    }
  };

  if (arg.includes("/editer")) {
    winData = {
      ...winData,
      width: 1100,
      height: 700,
      minWidth: 1100,
      minHeight: 700
    };
  }

  editerWin = new BrowserWindow(winData);

  // 打开调试工具
  editerWin.webContents.openDevTools();

  if (process.env.VITE_DEV_SERVER_URL) {
    editerWin.loadURL(`${url}#${arg}`);
  } else {
    editerWin.loadFile(indexHtml, { hash: arg });
  }
});

// 打开本地目录文件
async function handleFileOpen() {
  const { canceled, filePaths } = await dialog.showOpenDialog({
    properties: ["openDirectory"]
  });

  if (!canceled) {
    return filePaths[0];
  }
}

ipcMain.handle("dialog:openFile", handleFileOpen);

// 存储数据
ipcMain.handle("setStore", (event, key, value) => {
  return store.set(key, value);
});

// 获取数据
ipcMain.handle("getStore", (event, key) => {
  return store.get(key);
});

// 删除某一条数据
ipcMain.handle("deleteStore", (event, key) => {
  return store.delete(key);
});

// 清空所有数据
ipcMain.handle("clearStore", () => {
  return store.clear();
});

// 递归遍历指定目录下的所有文件和文件夹
function getAllFiles(filePath: string) {
  let res = [];
  if (fs.existsSync(filePath)) {
    const files = fs.readdirSync(filePath);
    files.forEach((item) => {
      const currentFilePath = filePath + "/" + item;
      // 获取指定目录文件信息
      const stats = fs.statSync(currentFilePath);
      if (stats.isFile()) {
        res.push({
          type: "file",
          name: item,
          path: currentFilePath
        });
      } else if (stats.isDirectory()) {
        res.push({
          type: "directory",
          name: item,
          path: currentFilePath,
          children: getAllFiles(currentFilePath)
        });
      }
    });
  } else {
    console.warn(`指定的目录${filePath}不存在！`);
  }
  // 如果指定目录内没有文件夹了，结束递归遍历
  return res;
}

// 判断指定目录知否存在
ipcMain.handle("exists", (event, filePath) => {
  const res = fs.existsSync(filePath);
  return res;
});

// 读取指定目录下的所有文件
ipcMain.handle("readdir", (event, filePath) => {
  const res = getAllFiles(filePath);
  return res;
});

// 删除指定目录下的所有文件
ipcMain.handle("rmdir", (event, filePath) => {
  /**
   * 删除文件夹功能
   * @param  {String} url  文件路径，绝对路径
   * @return {Null}
   */
  function deleteDir(url: string) {
    if (fs.existsSync(url)) {
      var files = [];
      //判断给定的路径是否存在
      files = fs.readdirSync(url); //返回文件和子目录的数组
      files.forEach(function (file, index) {
        var curPath = join(url, file);

        if (fs.statSync(curPath).isDirectory()) {
          //同步读取文件夹文件，如果是文件夹，则函数回调
          deleteDir(curPath);
        } else {
          fs.unlinkSync(curPath); //是指定文件，则删除
        }
      });

      fs.rmdirSync(url); //清除文件夹
    } else {
      console.warn(`指定的目录${url}不存在！`);
    }
  }
  const lastIndex = filePath.lastIndexOf("/");
  const parentPath = filePath.substring(0, lastIndex);
  const parentFiles = getAllFiles(parentPath);
  let directoryCount = 0;
  parentFiles.forEach((ele) => {
    if (ele.type === "directory") {
      directoryCount++;
    }
  });
  // 如果分类下只有一本书籍，连带分类一块删除，否则，只删除书籍
  if (directoryCount <= 1) {
    deleteDir(parentPath);
  } else {
    deleteDir(filePath);
  }
  return true;
});

// 删除文件
ipcMain.handle("unlink", (event, filePath) => {
  try {
    fs.unlinkSync(filePath);
    return true;
  } catch (error) {
    console.log(error);
    return false;
  }
});

// 递归创建目录 同步方法
function mkdirsSync(name: string) {
  if (fs.existsSync(name)) {
    return true;
  } else {
    if (mkdirsSync(dirname(name))) {
      fs.mkdirSync(name);
      return true;
    }
  }
}

// 创建文件夹
ipcMain.handle("mkdir", (event, filePath) => {
  if (filePath) {
    mkdirsSync(filePath);
    return true;
  }
  return false;
});

// 创建和写入文件
ipcMain.handle("writeFile", (event, filePath, data = "") => {
  if (filePath) {
    try {
      fs.writeFileSync(filePath, data, "utf8");
    } catch (error) {
      console.log(error);
      return false;
    }
    return true;
  }
  return false;
});

// 创建书籍文件夹，工作区路径/书籍类型/书籍名称
ipcMain.handle("createBookDir", (event, filePath, data) => {
  const { name, genre, summary } = data;
  if (!name || !genre || !summary) {
    return console.error("创建书籍信息有误");
  }
  const dir = filePath + "/" + genre + "/" + name;
  mkdirsSync(dir);
  try {
    fs.writeFileSync(dir + "/mzBook.json", JSON.stringify(data), "utf8");
    // 创建新书的时候，顺带创建正文文件夹和第一章文本
    fs.mkdirSync(dir + "/正文");
    // 创建一个空的第一章.txt文件
    fs.writeFileSync(dir + "/正文/第一章.txt", "", "utf8");
  } catch (error) {
    console.log(error);
    return false;
  }
  return true;
});

// 重命名目录或文件
function rename(oldPath: string, newPath: string) {
  try {
    fs.renameSync(oldPath, newPath);
  } catch (error) {
    console.log(error);
    return false;
  }
}

// 重命名目录或文件
ipcMain.handle("rename", (event, oldPath, newPath) => {
  rename(oldPath, newPath);
  return true;
});

// 编辑书籍基本信息，名称，分类和简介
ipcMain.handle("updateBook", (event, oldPath, newPath, data) => {
  const { name, genre, summary } = data;
  if (!name || !genre || !summary) {
    return console.error("修改书籍信息有误");
  }
  rename(oldPath, newPath);
  try {
    fs.writeFileSync(newPath + "/mzBook.json", JSON.stringify(data), "utf8");
  } catch (error) {
    console.log(error);
    return false;
  }
  return true;
});

// 根据指定路径读文件内容
ipcMain.handle("readFile", (event, filePath) => {
  if (fs.existsSync(filePath)) {
    const res = fs.readFileSync(filePath);
    return res.toString();
  } else {
    console.warn(`指定的目录${filePath}不存在！`);
  }
  return false;
});
